﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using System.Security.Cryptography;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;

namespace AdverseEventReportSystem.Utils {
    public class WebUtils {
        #region 获取网站的真实路径
        /// <summary>
        /// 获取网站的真实路径
        /// </summary>
        /// <returns></returns>
        public static string GetWebSiteReallyPath() {
            string path = HttpContext.Current.Request.Path;
            if (path.LastIndexOf("/") != path.IndexOf("/")) {
                path = path.Substring(path.IndexOf("/"), path.LastIndexOf("/") + 1);
            } else {
                path = "/";
            }
            return path;

        }
        #endregion
        #region 获取当前绝对路径
        /// <summary>
        /// 获取当前绝对路径
        /// </summary>
        /// <param name="strPath">指定的路径</param>
        /// <returns>绝对路径</returns>
        public static string GetMapPath(string strPath) {
            if (HttpContext.Current != null) {
                return HttpContext.Current.Server.MapPath(strPath);
            } else //非web程序引用
            {
                strPath = strPath.TrimStart('~');
                strPath = strPath.Replace("/", "\\");
                strPath = strPath.Replace("\\", "\\");
                if (strPath.StartsWith("\\")) {
                    strPath = strPath.TrimStart('\\');
                }
                return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
            }
        }
        #endregion
        #region 取得网站根目录的物理路径
        /// <summary>
        /// 取得网站根目录的物理路径
        /// </summary>
        public static string RootPhysicalPath {
            get {
                return System.Web.HttpContext.Current.Request.PhysicalApplicationPath;
            }
        }
        #endregion
        #region 时间相关
        /// <summary> 
        /// 取指定日期是一年中的第几周 
        /// </summary> 
        /// <param name="dtime">给定的日期</param> 
        /// <returns>数字 一年中的第几周</returns> 
        public static int WeekOfYear(DateTime dtime) {
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(dtime, CalendarWeekRule.FirstDay, DayOfWeek.Monday);

        }
        /// <summary>
        /// 获取某一年有多少周
        /// </summary>
        /// <param name="year">年份</param>
        /// <returns>该年周数</returns>
        public static int GetWeekAmount(int year) {
            DateTime end = new DateTime(year, 12, 31);  //该年最后一天
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(end, CalendarWeekRule.FirstDay, DayOfWeek.Monday);  //该年星期数
        }

        /// <summary>
        /// 时间单位枚举
        /// </summary>
        public enum DateInterval {
            Second, Minute, Hour, Day, Week, Month, Quarter, Year
        }

        /// <summary>
        /// 获取两个日期直接的差
        /// </summary>
        /// <param name="Interval">时间单位枚举</param>
        /// <param name="StartDate">开始日期</param>
        /// <param name="EndDate">结束日期</param>
        /// <returns></returns>
        public static long DateDiff(DateInterval Interval, DateTime StartDate, DateTime EndDate) {
            long lngDateDiffValue = 0;
            System.TimeSpan TS = new System.TimeSpan(EndDate.Ticks - StartDate.Ticks);
            switch (Interval) {
                case DateInterval.Second:
                    lngDateDiffValue = (long)TS.TotalSeconds;
                    break;
                case DateInterval.Minute:
                    lngDateDiffValue = (long)TS.TotalMinutes;
                    break;
                case DateInterval.Hour:
                    lngDateDiffValue = (long)TS.TotalHours;
                    break;
                case DateInterval.Day:
                    lngDateDiffValue = (long)TS.Days;
                    break;
                case DateInterval.Week:
                    lngDateDiffValue = (long)(TS.Days / 7);
                    break;
                case DateInterval.Month:
                    lngDateDiffValue = (long)(TS.Days / 30);
                    break;
                case DateInterval.Quarter:
                    lngDateDiffValue = (long)((TS.Days / 30) / 3);
                    break;
                case DateInterval.Year:
                    lngDateDiffValue = (long)(TS.Days / 365);
                    break;
            }
            return (lngDateDiffValue);
        }

        /// <summary>
        /// 取得某月的第一天
        /// </summary>
        /// <param name="datetime">要取得月份第一天的时间</param>
        /// <returns></returns>
        public static string FirstDayOfMonth(DateTime datetime)
        {
            return datetime.ToString("yyyy-MM-01");
        }

        /// <summary>
        /// 取得某月的最后一天
        /// </summary>
        /// <param name="datetime">要取得月份最后一天的时间</param>
        /// <returns></returns>
        public static string LastDayOfMonth(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfMonth(datetime), datetime).AddMonths(1).AddDays(-1).ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 取得上个月第一天
        /// </summary>
        /// <param name="datetime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static string FirstDayOfPreviousMonth(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfMonth(datetime), datetime).AddMonths(-1).ToString("yyyy-MM-dd");
        }

        //// <summary>
        /// 取得上个月的最后一天
        /// </summary>
        /// <param name="datetime">要取得上个月最后一天的当前时间</param>
        /// <returns></returns>
        public static string LastDayOfPrdviousMonth(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfMonth(datetime), datetime).AddDays(-1).ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 取得某年第一天
        /// </summary>
        /// <param name="datetime">要取得某年第一天的当前时间</param>
        /// <returns></returns>
        public static string FirstDayOfYear(DateTime datetime)
        {
            return datetime.ToString("yyyy-01-01");
        }

        //// <summary>
        /// 取得某年的最后一天
        /// </summary>
        /// <param name="datetime">要取得某年最后一天的当前时间</param>
        /// <returns></returns>
        public static string LastDayOfYear(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfYear(datetime), datetime).AddYears(1).AddDays(-1).ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 取得上一年第一天
        /// </summary>
        /// <param name="datetime">要取得上一年第一天的当前时间</param>
        /// <returns></returns>
        public static string FirstDayOfPreviousYear(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfYear(datetime), datetime).AddYears(-1).ToString("yyyy-MM-dd");
        }

        //// <summary>
        /// 取得上一年的最后一天
        /// </summary>
        /// <param name="datetime">要取得上一年最后一天的当前时间</param>
        /// <returns></returns>
        public static string LastDayOfPrdviousYear(DateTime datetime)
        {
            return DataConvert.StrToDateTime(FirstDayOfYear(datetime), datetime).AddDays(-1).ToString("yyyy-MM-dd");
        }

        #endregion
        #region Request操作
        /// <summary>
        /// 返回指定的服务器变量信息
        /// </summary>
        /// <param name="strName">服务器变量名</param>
        /// <returns>服务器变量信息</returns>
        public static string GetServerString(string strName) {
            //
            if (HttpContext.Current.Request.ServerVariables[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.ServerVariables[strName].ToString();
        }
        /// <summary>
        /// 得到当前完整主机头
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentFullHost() {
            HttpRequest request = HttpContext.Current.Request;
            if (!request.Url.IsDefaultPort) {
                return string.Format("{0}:{1}", request.Url.Host, request.Url.Port.ToString());
            }
            return request.Url.Host;
        }
        /// <summary>
        /// 得到主机头
        /// </summary>
        /// <returns></returns>
        public static string GetHost() {
            return HttpContext.Current.Request.Url.Host;
        }
        /// <summary>
        /// 获取当前请求的原始 URL(URL 中域信息之后的部分,包括查询字符串(如果存在))
        /// </summary>
        /// <returns>原始 URL</returns>
        public static string GetRawUrl() {
            return HttpContext.Current.Request.RawUrl;
        }
        public static string CombineRawUrl(string url) {
            if ((url[0] != '~') && (url.IndexOf(':') < 0)) {
                string rawUrl = HttpContext.Current.Request.RawUrl;
                if (rawUrl.IndexOf('?') > 0) {
                    rawUrl = rawUrl.Split(new char[] { '?' })[0];
                }
                if (url.IndexOf('?') > 0) {
                    string[] strArray = url.Split(new char[] { '?' });
                    url = VirtualPathUtility.Combine(rawUrl, strArray[0]) + "?" + strArray[1];
                    return url;
                }
                url = VirtualPathUtility.Combine(rawUrl, url);
            }
            return url;
        }
        /// <summary>
        /// 判断当前访问是否来自浏览器软件
        /// </summary>
        /// <returns>当前访问是否来自浏览器软件</returns>
        public static bool IsBrowserGet() {
            string[] BrowserName = { "ie", "opera", "netscape", "mozilla", "konqueror", "firefox" };
            string curBrowser = HttpContext.Current.Request.Browser.Type.ToLower();
            for (int i = 0; i < BrowserName.Length; i++) {
                if (curBrowser.IndexOf(BrowserName[i]) >= 0) {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 判断是否来自搜索引擎链接
        /// </summary>
        /// <returns>是否来自搜索引擎链接</returns>
        public static bool IsSearchEnginesGet() {
            string[] SearchEngine = { "google", "yahoo", "msn", "baidu", "sogou", "sohu", "sina", "163", "lycos", "tom", "yisou", "iask", "soso", "gougou", "zhongsou" };
            string tmpReferrer = HttpContext.Current.Request.UrlReferrer.ToString().ToLower();
            for (int i = 0; i < SearchEngine.Length; i++) {
                if (tmpReferrer.IndexOf(SearchEngine[i]) >= 0) {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 获得当前完整Url地址
        /// </summary>
        /// <returns>当前完整Url地址</returns>
        public static string GetUrl() {
            return HttpContext.Current.Request.Url.ToString();
        }
        /// <summary>
        /// 获得指定Url参数的值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <returns>Url参数的值</returns>
        public static string GetQueryString(string strName) {
            if (HttpContext.Current.Request.QueryString[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.QueryString[strName];
        }
        /// <summary>
        /// 获得当前页面的名称
        /// </summary>
        /// <returns>当前页面的名称</returns>
        public static string GetPageName() {
            string[] urlArr = HttpContext.Current.Request.Url.AbsolutePath.Split('/');
            return urlArr[urlArr.Length - 1].ToLower();
        }
        /// <summary>
        /// 返回表单或Url参数的总个数
        /// </summary>
        /// <returns></returns>
        public static int GetParamCount() {
            return HttpContext.Current.Request.Form.Count + HttpContext.Current.Request.QueryString.Count;
        }
        /// <summary>
        /// 获得指定表单参数的值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <returns>表单参数的值</returns>
        public static string GetFormString(string strName) {
            if (HttpContext.Current.Request.Form[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.Form[strName];
        }
        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">参数</param>
        /// <returns>Url或表单参数的值</returns>
        public static string GetString(string strName) {
            if ("".Equals(GetQueryString(strName))) {
                return GetFormString(strName);
            } else {
                return GetQueryString(strName);
            }
        }
        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值,并过滤非法字符
        /// </summary>
        /// <param name="strName">参数</param>
        /// <returns>Url或表单参数的值</returns>
        public static string GetSafeString(string strName) {
            string val = "";
            if ("".Equals(GetQueryString(strName))) {
                val = GetFormString(strName);
            } else {
                val = GetQueryString(strName);
            }
            val = val.Replace("'", "‘").Trim();
            val = StringHelper.FilterScript(val, "a,body,script,iframe,object");
            return val;
        }
        /// <summary>
        /// 获得指定Url参数的int类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static int GetQueryInt(string strName, int defValue = 0) {
            return DataConvert.StrToInt(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url参数的long类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static long GetQueryLong(string strName, long defValue = 0) {
            return DataConvert.StrToLong(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的int类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的int类型值</returns>
        public static int GetFormInt(string strName, int defValue = 0) {
            return DataConvert.StrToInt(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的long类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的long类型值</returns>
        public static long GetFormLong(string strName, long defValue = 0) {
            return DataConvert.StrToLong(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url或表单参数的long类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的long类型值</returns>
        public static long GetLong(string strName, long defValue = 0) {
            if (GetQueryLong(strName, defValue) == defValue) {
                return GetFormLong(strName, defValue);
            } else {
                return GetQueryLong(strName, defValue);
            }
        }
        /// <summary>
        /// 获得指定Url或表单参数的int类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的int类型值</returns>
        public static int GetInt(string strName, int defValue = 0) {
            if (GetQueryInt(strName, defValue) == defValue) {
                return GetFormInt(strName, defValue);
            } else {
                return GetQueryInt(strName, defValue);
            }
        }
        /// <summary>
        /// 获得指定Url参数的float类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static float GetQueryFloat(string strName, float defValue = 0) {
            return DataConvert.StrToFloat(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的float类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的float类型值</returns>
        public static float GetFormFloat(string strName, float defValue = 0) {
            return DataConvert.StrToFloat(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url或表单参数的float类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的int类型值</returns>
        public static float GetFloat(string strName, float defValue = 0) {
            if (GetQueryFloat(strName, defValue) == defValue) {
                return GetFormFloat(strName, defValue);
            } else {
                return GetQueryFloat(strName, defValue);
            }
        }

        /// <summary>
        /// 客户端IP地址，如果获取不到返回 0.0.0.0
        /// </summary>
        public static string ClientIP {
            get {
                var context = HttpContext.Current;
                string result = context.Request.UserHostAddress;
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                }
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.ServerVariables["REMOTE_ADDR"];
                }
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.UserHostAddress;
                }
                return result;
            }
        }
        public static bool IsLanIP(string IP) {
            var result = false;
            var ips = new List<string>() { "10.", "192.", "172.", "127.", "::1", "localhost" };
            ips.ForEach(x => {
                if (IP.StartsWith(x)) result = true;
            });
            return result;
        }
        /// <summary>
        /// 客户端主机名称
        /// </summary>
        public static string ClientHostName {
            get {
                var context = HttpContext.Current;
                string IP = context.Request.UserHostAddress;
                string Name = context.Request.UserHostName;

                if (Name == IP || Name == "127.0.0.1" || Name == "::1") {
                    Name = context.Request.ServerVariables["REMOTE_HOST"];
                }
                if (Name == IP || Name == "127.0.0.1" || Name == "::1") {
                    try { Name = Dns.GetHostEntry(IP).HostName; } catch { }
                }
                return Name;
            }
        }
        /// <summary>
        /// 获取Form的参数和值拼接后的字段串
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetFormString(HttpContext context) {
            string re = context.Request.Form.ToString();
            return re;
        }
        /// <summary>
        /// 获取request的参数和值拼接后的字段串
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetQueryString(HttpContext context) {
            string re = context.Request.QueryString.ToString();
            return re;
        }
        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>编码结果</returns>
        public static string UrlEncode(string str) {
            return HttpUtility.UrlEncode(str);
        }
        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string str) {
            return HttpUtility.UrlDecode(str);
        }
        #endregion
        #region Session操作
        /// <summary>
        /// 读Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>Session值</returns>
        public static string GetSession(string strName) {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[strName] != null) {
                string value = HttpContext.Current.Session[strName].ToString();
                return value;
            }
            return WriteSession(strName, "");
        }
        /// <summary>
        /// 写入Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>Session值</returns>
        public static string WriteSession(string strName, string value) {
            if (HttpContext.Current == null) {
                return "";
            }
            HttpContext.Current.Session[strName] = value;
            return value;
        }
        /// <summary>
        /// 清除Session
        /// </summary>
        /// <param name="name">name of Session</param>
        public static void RemoveSession(string name) {
            if (HttpContext.Current.Session[name] != null) {
                HttpContext.Current.Session.Remove(name);
            }
        }
        /// <summary>
        ///  读Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns>Session值</returns>
        public static int GetSessionInt(string strName, int defaultValue) {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[strName] != null) {
                return DataConvert.StrToInt(HttpContext.Current.Session[strName]);
            }

            return defaultValue;
        }
        #endregion
        #region Post And Get
        public static string DoGet(string url) {
            string rs = "";
            try {
                string xmlContent = "";
                HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create(url);
                HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
                StreamReader sr = new StreamReader(HttpWResp.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8"));
                xmlContent = sr.ReadToEnd().Trim();
                sr.Close();
                HttpWResp.Close();
                HttpWReq.Abort();
                rs = xmlContent;

            } catch (Exception ex) {
                rs = "";
                return ex.Message;
            }

            return rs;
        }
        /// <summary>
        /// 提交Get请求并获取输出内容
        /// </summary>
        /// <param name="url"></param>
        /// <param name="parameters">提交参数</param>
        /// <returns></returns>
        public static string DoGet(string url, IDictionary<string, string> parameters) {
            if ((parameters != null) && (parameters.Count > 0)) {
                if (url.Contains("?")) {
                    url = url + "&" + BuildPostData(parameters);
                } else {
                    url = url + "?" + BuildPostData(parameters);
                }
            }
            HttpWebRequest request;
            //如果是发送HTTPS请求   
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) {
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            } else {
                request = (HttpWebRequest)WebRequest.Create(url);
            }
            request.Method = "GET";
            request.KeepAlive = false;
            request.UserAgent = "U1city";
            request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            HttpWebResponse rsp = (HttpWebResponse)request.GetResponse();
            Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet);
            return GetResponseString(rsp, encoding);
        }
        /// <summary>
        /// 提交Post请求并获取输出内容
        /// </summary>
        /// <param name="url">URL地址</param>
        /// <param name="param">提交参数。示例 key1=value1&key2=value2</param>
        /// <returns></returns>
        public static string DoPost(string url, string param) {
            if (url == "") {
                return "url未配置";
            }

            System.Text.Encoding encode = System.Text.Encoding.UTF8;
            string strRequestData = param;

            //把数组转换成流中所需字节数组类型
            byte[] bytesRequestData = encode.GetBytes(strRequestData);


            //请求远程HTTP
            string strResult = "";
            try {
                //设置HttpWebRequest基本信息
                HttpWebRequest request;
                //如果是发送HTTPS请求   
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) {
                    ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                    request = WebRequest.Create(url) as HttpWebRequest;
                    request.ProtocolVersion = HttpVersion.Version10;
                } else {
                    request = (HttpWebRequest)WebRequest.Create(url);
                }
                request.Method = "post";
                request.KeepAlive = false;
                request.UserAgent = "U1city";
                request.ContentType = "application/x-www-form-urlencoded";

                //填充POST数据
                request.ContentLength = bytesRequestData.Length;
                Stream requestStream = request.GetRequestStream();
                requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
                requestStream.Close();

                //发送POST数据请求服务器
                HttpWebResponse HttpWResp = (HttpWebResponse)request.GetResponse();
                Stream myStream = HttpWResp.GetResponseStream();

                //获取服务器返回信息
                StreamReader reader = new StreamReader(myStream, encode);

                strResult = reader.ReadToEnd();
                reader.Close();

                //释放
                myStream.Close();

            } catch (Exception exp) {
                strResult = "报错：" + exp.Message;
            }

            return strResult;
        }
        /// <summary>
        /// 提交Post请求并获取输出内容
        /// </summary>
        /// <param name="url">URL地址</param>
        /// <param name="formDataDict">提交参数</param>
        /// <returns></returns>
        public static string DoPost(string url, IDictionary<string, string> formDataDict) {
            string strRequestData = BuildPostData(formDataDict);
            return DoPost(url, strRequestData);
        }
        /// <summary>
        /// 获取输出字符串内容
        /// </summary>
        /// <param name="rsp"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        private static string GetResponseString(HttpWebResponse rsp, Encoding encoding) {
            string strResult = string.Empty;
            Stream responseStream = null;
            StreamReader reader = null;
            try {
                responseStream = rsp.GetResponseStream();
                reader = new StreamReader(responseStream, encoding);
                strResult = reader.ReadToEnd();
                reader.Close();
            } finally {
                if (reader != null) {
                    reader.Close();
                }
                if (responseStream != null) {
                    responseStream.Close();
                }
                if (rsp != null) {
                    rsp.Close();
                }
            }
            return strResult;
        }
        /// <summary>
        ///  把参数添加到post请求流里面
        /// </summary>
        /// <param name="memStream">MemoryStream</param>
        /// <param name="formDataDict"></param>
        /// <param name="boundary"></param>
        private static void AddFormData(MemoryStream memStream, IDictionary<string, string> formDataDict, string boundary) {
            //没有form参数的情况下，直接返回
            if (formDataDict == null || formDataDict.Keys.Count == 0) {
                return;
            }

            // 写入字符串的Key  
            var stringKeyHeader = "\r\n--" + boundary +
                                   "\r\nContent-Disposition: form-data; name=\"{0}\"" +
                                   "\r\n\r\n{1}";

            //将需要提交的form的参数信息，设置到post请求流里面
            foreach (byte[] formitembytes in from string key in formDataDict.Keys
                                             select string.Format(stringKeyHeader, key, formDataDict[key])
                                                 into formitem
                                                 select Encoding.UTF8.GetBytes(formitem)) {
                memStream.Write(formitembytes, 0, formitembytes.Length);
            }

        }
        private static bool CheckValidationResult(object sender,
            System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors) {
            return true;// Always accept
        }
        /// <summary>
        /// 生成Post请求字符串
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private static string BuildPostData(IDictionary<string, string> parameters) {
            StringBuilder builder = new StringBuilder();
            bool flag = false;
            IEnumerator<KeyValuePair<string, string>> enumerator = parameters.GetEnumerator();
            while (enumerator.MoveNext()) {
                KeyValuePair<string, string> current = enumerator.Current;
                string key = current.Key;
                string str2 = current.Value;
                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(str2)) {
                    if (flag) {
                        builder.Append("&");
                    }
                    builder.Append(key);
                    builder.Append("=");
                    builder.Append(Uri.EscapeDataString(str2));
                    flag = true;
                }
            }
            return builder.ToString();
        }
        #endregion
        #region 下载文件
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="FileFullPath">下载文件下载的完整路径及名称</param>
        public static void DownLoadFile(string FileFullPath) {
            if (!string.IsNullOrEmpty(FileFullPath) && File.Exists(FileFullPath)) {
                FileInfo fi = new FileInfo(FileFullPath);//文件信息
                string browser = HttpContext.Current.Request.UserAgent.ToUpper();
                string fileName = browser.Contains("FIREFOX") ? fi.Name : HttpUtility.UrlEncode(fi.Name); //对文件名编码
                fileName = fileName.Replace("+", "%20"); //解决空格被编码为"+"号的问题

                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ContentType = "application/octet-stream";
                HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
                HttpContext.Current.Response.AppendHeader("content-length", fi.Length.ToString()); //文件长度
                int chunkSize = 102400;//缓存区大小,可根据服务器性能及网络情况进行修改
                byte[] buffer = new byte[chunkSize]; //缓存区
                using (FileStream fs = fi.Open(FileMode.Open))  //打开一个文件流
                {
                    while (fs.Position >= 0 && HttpContext.Current.Response.IsClientConnected) //如果没到文件尾并且客户在线
                    {
                        int tmp = fs.Read(buffer, 0, chunkSize);//读取一块文件
                        if (tmp <= 0) break; //tmp=0说明文件已经读取完毕,则跳出循环
                        HttpContext.Current.Response.OutputStream.Write(buffer, 0, tmp);//向客户端传送一块文件
                        HttpContext.Current.Response.Flush();//保证缓存全部送出
                        Thread.Sleep(10);//主线程休息一下,以释放CPU
                    }
                }
            }
        }
        #endregion
        #region 下载大文件 支持续传、速度限制
        /// <summary>
        /// 下载大文件 支持续传、速度限制
        /// </summary>
        /// <param name="context">当前请求的HttpContext</param>
        /// <param name="filePath">下载文件的物理路径，含路径、文件名</param>
        /// <param name="speed">下载速度：每秒允许下载的字节数</param>
        /// <returns>true下载成功，false下载失败</returns>
        public static bool DownloadFile(HttpContext context, string filePath, long speed) {
            string fileName = Path.GetFileName(filePath);
            Stream myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            return DownloadFile(context, myFile, fileName, speed);
        }
        /// <summary>
        /// 下载文件，支持大文件、续传、速度限制。支持续传的响应头Accept-Ranges、ETag，请求头Range 。
        /// Accept-Ranges：响应头，向客户端指明，此进程支持可恢复下载.实现后台智能传输服务（BITS），值为：bytes；
        /// ETag：响应头，用于对客户端的初始（200）响应，以及来自客户端的恢复请求，
        /// 必须为每个文件提供一个唯一的ETag值（可由文件名和文件最后被修改的日期组成），这使客户端软件能够验证它们已经下载的字节块是否仍然是最新的。
        /// Range：续传的起始位置，即已经下载到客户端的字节数，值如：bytes=1474560- 。
        /// 另外：UrlEncode编码后会把文件名中的空格转换中+（+转换为%2b），但是浏览器是不能理解加号为空格的，所以在浏览器下载得到的文件，空格就变成了加号；
        /// 解决办法：UrlEncode 之后, 将 "+" 替换成 "%20"，因为浏览器将%20转换为空格
        /// </summary>
        /// <param name="context">当前请求的HttpContext</param>
        /// <param name="filePath">下载文件的物理路径，含路径、文件名</param>
        /// <param name="speed">下载速度：每秒允许下载的字节数</param>
        /// <returns>true下载成功，false下载失败</returns>
        public static bool DownloadFile(HttpContext context, Stream myFile, string fileName, long speed) {
            bool ret = true;
            try {
                #region 定义局部变量
                long startBytes = 0;
                int packSize = 1024 * 10; //分块读取，每块10K bytes

                //FileStream myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                BinaryReader br = new BinaryReader(myFile);
                long fileLength = myFile.Length;

                int sleep = (int)Math.Ceiling(1000.0 * packSize / speed);//毫秒数：读取下一数据块的时间间隔
                //string lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
                //string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr;//便于恢复下载时提取请求头;
                #endregion

                #region--验证：文件是否太大，是否是续传，且在上次被请求的日期之后是否被修改过--------------
                if (myFile.Length > Int32.MaxValue) {//-------文件太大了-------
                    context.Response.StatusCode = 413;//请求实体太大
                    return false;
                }

                //if (context.Request.Headers["If-Range"] != null)//对应响应头ETag：文件名+文件最后修改时间
                //{
                //    //----------上次被请求的日期之后被修改过--------------
                //    if (context.Request.Headers["If-Range"].Replace("\"", "") != eTag)
                //    {//文件修改过
                //        context.Response.StatusCode = 412;//预处理失败
                //        return false;
                //    }
                //}
                #endregion

                try {
                    #region -------添加重要响应头、解析请求头、相关验证-------------------
                    context.Response.Clear();
                    context.Response.Buffer = false;
                    context.Response.AddHeader("Content-MD5", GetHashMD5(myFile));//用于验证文件
                    context.Response.AddHeader("Accept-Ranges", "bytes");//重要：续传必须
                    //context.Response.AppendHeader("ETag", "\"" + eTag + "\"");//重要：续传必须
                    //context.Response.AppendHeader("Last-Modified", lastUpdateTiemStr);//把最后修改日期写入响应              
                    context.Response.ContentType = "application/octet-stream";//MIME类型：匹配任意文件类型
                    context.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20"));
                    context.Response.AddHeader("Content-Length", (fileLength - startBytes).ToString());
                    context.Response.AddHeader("Connection", "Keep-Alive");
                    context.Response.ContentEncoding = Encoding.UTF8;
                    if (context.Request.Headers["Range"] != null) {
                        //------如果是续传请求，则获取续传的起始位置，即已经下载到客户端的字节数------
                        context.Response.StatusCode = 206;//重要：续传必须，表示局部范围响应。初始下载时默认为200
                        string[] range = context.Request.Headers["Range"].Split(new char[] { '=', '-' });//"bytes=1474560-"
                        startBytes = Convert.ToInt64(range[1]);//已经下载的字节数，即本次下载的开始位置
                        if (startBytes < 0 || startBytes >= fileLength) {
                            //无效的起始位置
                            return false;
                        }
                    }
                    if (startBytes > 0) {
                        //------如果是续传请求，告诉客户端本次的开始字节数，总长度，以便客户端将续传数据追加到startBytes位置后----------
                        context.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
                    }
                    #endregion


                    #region -------向客户端发送数据块-------------------
                    br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
                    int maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize);//分块下载，剩余部分可分成的块数
                    for (int i = 0; i < maxCount && context.Response.IsClientConnected; i++) {//客户端中断连接，则暂停
                        context.Response.BinaryWrite(br.ReadBytes(packSize));
                        context.Response.Flush();
                        if (sleep > 1) Thread.Sleep(sleep);
                    }
                    #endregion
                } catch {
                    ret = false;
                } finally {
                    br.Close();
                    myFile.Close();
                }
            } catch {
                ret = false;
            }
            return ret;
        }
        #endregion
        #region 下载文件，用cookies记录下载状态，源自microsoft Ajax File Download
        //writefile
        public static void DownloadFile(HttpContext context, string fileName) {
            HttpResponse response = context.Response;
            HttpCookie cookie = context.Request.Cookies["downloadstatus"];
            if (cookie == null) {
                cookie = new HttpCookie("downloadstatus", String.Empty);
            }
            HttpCookie errorCookie = new HttpCookie("downloaderror", string.Empty);
            FileInfo TheFile = new FileInfo(fileName);
            if (TheFile.Exists) {
                response.Clear();
                cookie.Value = "success";
                response.SetCookie(cookie);
                response.Buffer = true;
                response.AddHeader("content-disposition", "attachment;filename=" + TheFile.Name);
                response.Charset = "";
                response.ContentType = GetContentType(TheFile.Name);
                //response.WriteFile(TheFile.FullName);      
                response.TransmitFile(TheFile.FullName); //WriteFile改良版
                response.Flush();
                response.End();
            } else {
                cookie.Value = "fail";
                errorCookie.Value = "File " + TheFile.Name + " doesn't exists on the server";
                response.SetCookie(cookie);
                response.SetCookie(errorCookie);
            }
        }
        #endregion
        #region GetHashMD5
        /// <summary>
        /// method for getting a files MD5 hash, say for
        /// a checksum operation
        /// </summary>
        /// <param name="file">the file we want the has from</param>
        /// <returns></returns>
        private static string GetHashMD5(Stream stream) {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            md5.ComputeHash(stream);
            byte[] hash = md5.Hash;
            StringBuilder sb = new StringBuilder();
            foreach (byte b in hash) {
                sb.Append(string.Format("{0:X2}", b));
            }
            return sb.ToString();
        }

        private static string GetHashMD5(string file) {
            FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 8192);
            string hashMD5 = GetHashMD5(stream);
            stream.Close();
            return hashMD5;
        }
        #endregion
        #region GetContentType
        /// <summary>
        /// GetContentType
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <returns></returns>
        private static string GetContentType(string fileName) {
            string contentType = "application/octetstream";
            string ext = Path.GetExtension(fileName).ToLower();
            Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
            if (registryKey != null && registryKey.GetValue("Content Type") != null)
                contentType = registryKey.GetValue("Content Type").ToString();
            return contentType;
        }
        #endregion
        #region 循环去除datatable中的空行
        /// <summary>
        /// 循环去除datatable中的空行
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DataTable removeEmpty(DataTable dt) {
            List<DataRow> removelist = new List<DataRow>();
            for (int i = 0; i < dt.Rows.Count; i++) {
                bool rowdataisnull = true;
                for (int j = 0; j < dt.Columns.Count; j++) {

                    if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim())) {

                        rowdataisnull = false;
                    }

                }
                if (rowdataisnull) {
                    removelist.Add(dt.Rows[i]);
                }

            }
            for (int i = 0; i < removelist.Count; i++) {
                dt.Rows.Remove(removelist[i]);
            }

            return dt;
        }
        #endregion
        #region 上传图片
        /// <summary>
        /// 上传图片
        /// </summary>
        /// <param name="base64String">图片的base64字符串</param>
        /// <param name="filePath">保存路径</param>
        /// <param name="fileName">图片名称没有后缀名</param>
        /// <returns>返回完整图片名称</returns>
        public static string UploadPic(string base64String, string filePath, string fileName) {
            byte[] imageBytes = Convert.FromBase64String(base64String);
            //读入MemoryStream对象
            MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
            memoryStream.Write(imageBytes, 0, imageBytes.Length);
            //转成图片
            Image image = Image.FromStream(memoryStream);
            //文件后缀名
            string extension = "";
            ImageFormat imgformat = null;
            if (image.RawFormat.Guid.ToString().Equals(ImageFormat.Jpeg.Guid.ToString())) {
                imgformat = ImageFormat.Jpeg;
                extension = ".jpg";
            }
            if (image.RawFormat.Guid.ToString().Equals(ImageFormat.Bmp.Guid.ToString())) {
                imgformat = ImageFormat.Bmp;
                extension = ".bmp";
            }
            if (image.RawFormat.Guid.ToString().Equals(ImageFormat.Gif.Guid.ToString())) {
                imgformat = ImageFormat.Gif;
                extension = ".gif";
            }
            if (image.RawFormat.Guid.ToString().Equals(ImageFormat.Png.Guid.ToString())) {
                imgformat = ImageFormat.Png;
                extension = ".png";
            }
            if (imgformat == null) {
                imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
            }

            image.Save(filePath + fileName + extension, imgformat);
            return fileName + extension;
        }
        #endregion
    }
}
